{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os, argparse\n",
    "import tensorflow as tf\n",
    "from tensorflow.python.framework import graph_util\n",
    "\n",
    "dir = os.path.dirname(os.path.realpath(__file__))\n",
    "\n",
    "def freeze_graph(model_folder):\n",
    "    # We retrieve our checkpoint fullpath\n",
    "    checkpoint = tf.train.get_checkpoint_state(model_folder)\n",
    "    input_checkpoint = checkpoint.model_checkpoint_path\n",
    "\n",
    "    # We precise the file fullname of our freezed graph\n",
    "    absolute_model_folder = \"/\".join(input_checkpoint.split('/')[:-1])\n",
    "    output_graph = absolute_model_folder + \"/frozen_model.pb\"\n",
    "\n",
    "    # Before exporting our graph, we need to precise what is our output node\n",
    "    # this variables is plural, because you can have multiple output nodes\n",
    "    #freeze之前必须明确哪个是输出结点,也就是我们要得到推论结果的结点\n",
    "    #输出结点可以看我们模型的定义\n",
    "    #只有定义了输出结点,freeze才会把得到输出结点所必要的结点都保存下来,或者哪些结点可以丢弃\n",
    "    #所以,output_node_names必须根据不同的网络进行修改\n",
    "    output_node_names = \"Accuracy/predictions\"\n",
    "\n",
    "    # We clear the devices, to allow TensorFlow to control on the loading where it wants operations to be calculated\n",
    "    clear_devices = True\n",
    "\n",
    "    # We import the meta graph and retrive a Saver\n",
    "    saver = tf.train.import_meta_graph(input_checkpoint + '.meta', clear_devices=clear_devices)\n",
    "\n",
    "    # We retrieve the protobuf graph definition\n",
    "    graph = tf.get_default_graph()\n",
    "    input_graph_def = graph.as_graph_def()\n",
    "\n",
    "    #We start a session and restore the graph weights\n",
    "    #这边已经将训练好的参数加载进来,也即最后保存的模型是有图,并且图里面已经有参数了,所以才叫做是frozen\n",
    "    #相当于将参数已经固化在了图当中 \n",
    "    with tf.Session() as sess:\n",
    "        saver.restore(sess, input_checkpoint)\n",
    "\n",
    "        # We use a built-in TF helper to export variables to constant\n",
    "        output_graph_def = graph_util.convert_variables_to_constants(\n",
    "            sess, \n",
    "            input_graph_def, \n",
    "            output_node_names.split(\",\") # We split on comma for convenience\n",
    "        ) \n",
    "\n",
    "        # Finally we serialize and dump the output graph to the filesystem\n",
    "        with tf.gfile.GFile(output_graph, \"wb\") as f:\n",
    "            f.write(output_graph_def.SerializeToString())\n",
    "        print(\"%d ops in the final graph.\" % len(output_graph_def.node))\n",
    "\n",
    "if __name__ == '__main__':\n",
    "\n",
    "    freeze_graph(\"model\")\n",
    "    \n",
    "    "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
